package com.northpool.operator.dataset.spatial;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.annotation.OutputParam;
import com.northpool.operator.annotation.OutputParams;
import com.northpool.operator.common.algorithm.OperatorTestBuild;
import com.northpool.operator.common.algorithm.TestParamBuilder;
import com.northpool.operator.common.database.DatabaseUtils;
import com.northpool.operator.exception.ParamException;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.type.TypeEnum;
import com.northpool.operator.utils.StpOperatorHelper;
import com.northpool.resources.datasource.IDataSource;
import com.northpool.resources.datatable.operate.IColumn;
import com.northpool.resources.datatable.operate.ITableOperator;
import com.northpool.spatial.Constants;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

@OperatorInfo(
        ref = "SpatialInfoOperator",
        name = "空间信息获取",
        description = "空间表的空间信息获取"
)
@OutputParams({
        @OutputParam(ref = "srid", name = "SRID", desc = "空间字段的SRID"),
        @OutputParam(ref = "spatialField", name = "空间字段", desc = "空间字段名称"),
        @OutputParam(ref = "spatialType", name = "几何类型", desc = "空间字段的几何类型")
})
public class SpatialInfoOperator extends StpOperatorHelper {

    @InputParams({
            @InputParam(ref = "datasource", name = "数据源", desc = "数据源ID", type = TypeEnum.DATASOURCE, required = true),
            @InputParam(ref = "tableName", name = "表名称", desc = "数据表名称，如: tb_test", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "spatialField", name = "空间字段名称", desc = "数据表名称，如: tb_test", type = TypeEnum.STRING, required = false),
    })
    public SpatialInfoOperator() {
    }

    public static void main(String[] args) {
        OperatorTestBuild.execute(SpatialInfoOperator.class, TestParamBuilder.aBuilder()
                .param("datasource", "test_bcg")
                .param("tableName", "public.dltb_building_b_all")
                .param("spatialField", "geom")
                .build());
    }

    @Override
    public void execute(ParamTool paramTool) throws Exception {
        String dataSourceId = paramTool.getStr("datasource");
        String dataSourceJson = DatabaseUtils.getDataSourceJson(dataSourceId);
        String tableName = paramTool.getStr("tableName");
        String spatialField = paramTool.getStr("spatialField");
        IDataSource ds = IDataSource.fromJSON(dataSourceJson);

        ITableOperator tableOperator = ds.getTableOperator(tableName);
        List<String> spatialColumnList = tableOperator.getSpatialColumnList();
        if (spatialColumnList.isEmpty()) {
            this.error("数据表 {} 空间字段未找到", tableName);
            this.failedExit();
        } else if (spatialColumnList.size() > 1 && StringUtils.isBlank(spatialField)) {
            throw new ParamException("空间字段名称", "数据表存在多个空间字段时需指定空间字段名称");
        }
        if (StringUtils.isBlank(spatialField)) {
            spatialField = spatialColumnList.get(0);
        }
        Map<String, IColumn> columnMap = tableOperator.getColumnMap();
        IColumn iColumn = columnMap.get(spatialField);
        Constants.GEO_TYPE geoType = iColumn.getGeoType();
        this.result("srid", iColumn.getSRID());
        this.result("spatialType", geoType.name());
        this.result("spatialField", spatialField);
    }
}
